/**
 * @name ws连接类
 * @author weilan
 * @time 2021.01.29
 */
import { Time } from "wl-core"

class WebSocket {
  /**
   * @param {String} url 连接地址
   * @param {Object} options 重试次数
   * @argument {Function} message 消息监听函数
   * @argument {Function} error 连接错误
   * @argument {Function} close 连接关闭
   * @argument {Function} open 连接开启
   */
  constructor(url, options = {}) {
    // 代理及加密ws连接
    const base64_time = window.btoa(Time.quickFormat(new Date(), 'YYYY-MM-DD HH:mm:ss'));
    const wsIndex = Math.random();
    let url = (/^ws/.test(url) ? url : 'ws://' + window.location.host + url) + '?token=' + base64_time + "&index=" + wsIndex;
    this.ws = new WebSocket(url);
    // 代理ws回调函数
    this.ws.onclose = this.onClose;
    this.ws.onerror = this.onError;
    this.ws.onmessage = this.onMessage;
    this.ws.onopen = this.onOpen;
    // 记录ws当前状态
    this.readyState = this.ws.readyState;
    // 记录实例化options所设置回调函数
    this.instanceOnMessage = options.message;
    this.instanceOnError = options.error;
    this.instanceOnClose = options.close;
    this.instanceOnOpen = options.open;
    // 开启心跳保持ws活性
    this.keepAlive();
  }
  /**
   * 
   * @param {String} data 消息体，需要JSON.parse
   */
  onMessage({ data }) {
    this.instanceOnMessage(data)
  }
  /**
   * 连接错误回调
   * @param {Object} event 
   */
  onError(event) {
    console.log('webSocket Error: \n', event)
    this.instanceOnError(event)
  }
  // 连接关闭
  onClose(e) {
    this.readyState = this.ws.readyState;
    clearInterval(this.timer);
    this.timer = null;
    console.log('websocket 断开: ' + e.code + ', ' + e.reason + ', ' + e.wasClean + ', ' + Time.quickFormat(new Date(), 'YYYY-MM-DD HH:mm:ss'))
    this.instanceOnClose()
  }
  // 连接开启
  onOpen() {
    console.log('webSocket opened ' + Time.quickFormat(new Date(), 'YYYY-MM-DD HH:mm:ss'))
    this.readyState = this.ws.readyState;
    this.instanceOnOpen()
  }
  // 手动关闭连接
  close() {
    this.ws?.close?.();
  }
  // 发送数据
  send(data) {
    // 增加md5时间戳加密
    // const md5_time = md5(new Date().getTime()).toString()
    const ws_data = JSON.stringify(data);
    this.ws?.send(ws_data);
  }
  // 保持心跳
  keep() {
    this.timer = setInterval(() => {
      this.wsOnSend({ 'keep-alive': true })
    }, 60000)
  }
}